﻿using System.Linq;
using Microsoft.Practices.Unity;
using SDCloudSolution.SDCloud.BusinessLayer.Interfaces;
using SDCloudSolution.SDCloud.BusinessLayer.Model;
using SDCloudSolution.SDCloud.BusinessLayer.Model.Interfaces;
using SDCloudSolution.SDCloud.DataLayer.Interfaces;
using SDCloudSolution.SDCloud.DataLayer.Model;
using SDCloudSolution.SDCloud.DataLayer.Model.Interfaces;
using SDCloudSolution.SDCloud.DataLayer.ModelData;
using SDCloudSolution.SDCloud.DataLayer.ModelData.Interfaces;
using SDCloudSolution.SDCloud.DataLayer.MongoDb;
using SDCloudSolution.SDCloud.DataLayer.MongoDb.Interfaces;
using SDCloudSolution.SDCloud.ModelRunAgent.Infrastructure;
using SDCloudSolution.SDCloud.ModelRunAgent.Infrastructure.Engines;
using SDCloudSolution.SDCloud.ModelRunAgent.Infrastructure.Interfaces;

namespace SDCloudSolution.SDCloud.ModelRunAgent
{
    public static class UnityConfig
    {
        public static void Configurate(IUnityContainer container)
        {
            RegisterTypesByPattern(container);

            container.RegisterType<IModelRunDataProvider, ModelRunDataProvider>();
            container.RegisterType<IModelComponent, ModelComponent>();

            container.RegisterType<IModelExecutionResultDataProvider, MongoModelExecutionResultDataProvider>();

            container.RegisterType<ISdcloudMongoClient, SdcloudMongoClient>(new PerThreadLifetimeManager());

            RegisterConfigurations(container);
            RegisterModelExecutorEngines(container);
        }

        private static void RegisterConfigurations(IUnityContainer container)
        {
            container.RegisterType<IIdentityDbConnectionStringProvider, ApplicationSettingsProvider>();
            container.RegisterType<IFileStorageSettingsProvider, ApplicationSettingsProvider>();
            container.RegisterType<ISdCloudMongoDbSettingsProvider, ApplicationSettingsProvider>();

            container.RegisterType<IPysdServiceSettingsProvider, ApplicationSettingsProvider>();
        }

        private static void RegisterModelExecutorEngines(IUnityContainer container)
        {
            container.RegisterType<IModelExecutorFactory, PythonEngineModelExecutorFactory>();
        }

        private static void RegisterTypesByPattern(IUnityContainer container)
        {
            const string matchingSdCloudPattern = "SDCloudSolution.SDCloud";

            container.RegisterTypes(
                AllClasses.FromLoadedAssemblies()
                    .Where(assembly =>
                        !string.IsNullOrWhiteSpace(assembly.Namespace) &&
                        assembly.Namespace.Contains(matchingSdCloudPattern)),
                WithMappings.FromMatchingInterface,
                WithName.Default,
                WithLifetime.PerThread);
        }
    }
}
